#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>

#define FILE_NAME(number) "text.txt"#number// 将宏参数number转换成字符串，并将两个字符串合二为一

//
//// 文件标记位。每个宏对应的数值只有一个bit是1，且宏之间的1位不重叠
//#define ONE (1<<0)
//#define TWO (1<<1)
//#define THREE (1<<2)
//#define FOUR (1<<3)
//
//// 测试标记位
//void testShow(int flags)
//{
//    if(flags & ONE) printf("文件标记位：ONE\n");
//    if(flags & TWO) printf("文件标记位：TWO\n");
//    if(flags & THREE) printf("文件标记位：THREE\n");
//    if(flags & FOUR) printf("文件标记位：FOUR\n");
//}

int main()
{
    printf("stdin->fd:%d\n", stdin->_fileno);
    printf("stdout->fd:%d\n", stdout->_fileno);
    printf("stderr->fd:%d\n", stderr->_fileno);
    // 打开文件
    // O_WRONLY 以只写的方式打开。如果仅仅这样，若文件不存在，就会打开失败，这是因为：
    // 使用C语言库函数打开文件时，以只写的方式打开，如果没有，就会创建该文件。实际上是C语言的库函数是对open进行了封装处理，实际open应添加O_CREAT
    //int open(const char *pathname, int flags);
    //int open(const char *pathname, int flags, mode_t mode);// mode是创建文件的默认权限
    umask(0);// 设置当前进程创建文件的默认权限，即文件掩码 
    // C语言中，以w方式打开文件，会自动清空内部的数据，就是加了打开权限O_TRUNC
    int fd0 = open(FILE_NAME(0), O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd1 = open(FILE_NAME(1), O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd2 = open(FILE_NAME(2), O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd3 = open(FILE_NAME(3), O_WRONLY | O_CREAT | O_TRUNC, 0666);
    int fd4 = open(FILE_NAME(4), O_WRONLY | O_CREAT | O_TRUNC, 0666);
    //int fd = open(FILE_NAME, O_RDONLY, 0666);// 只读
    //int fd = open(FILE_NAME, O_WRONLY | O_CREAT | O_APPEND, 0666);// 追加
    //assert(fd != -1);// 确保文件成功打开
//    if(fd == -1)
//    {
//        perror("open");
//        return 1;
//    }
//
//    char buf[1024];
//    ssize_t num = read(fd, buf, sizeof(buf) - 1);
//    if(num > 0)
//    {
//        // 读取成功
//        buf[num] = 0;//添加结束标识符'\0'，意为buf是个字符
//    }
//    printf("%s\n", buf);

//    int cnt = 4;
//    char out_buffer[64];
//    while(cnt)
//    {
//        //sprintf(out_buffer, "%s:%d\n", "hello world!", cnt--);
//        sprintf(out_buffer, "%s:%d\n", "aaaaaa!", cnt--);
//        write(fd, out_buffer, strlen(out_buffer));
//    }


    //printf("fd:%d\n", fd);

    printf("fd0:%d\n", fd0);
    printf("fd1:%d\n", fd1);
    printf("fd2:%d\n", fd2);
    printf("fd3:%d\n", fd3);
    printf("fd4:%d\n", fd4);
    // 关闭文件
//    close(fd);
    close(fd0);
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);

//    testShow(ONE);
//    printf("\n");
//    testShow(TWO);
//    printf("\n");
//    testShow(ONE | THREE);
//    printf("\n");
//    testShow(TWO | THREE | FOUR);
//    printf("\n");

    //文本  
    //r只读,w只写
    //r+读写，文件不存在就出错
    //w+读写，文件不存在就创建
    //
    //r+b二进制读,w+b二进制写
    //
    //a追加，a+
    //FILE* fp = fopen(FILE_NAME, "w");
    //FILE* fp = fopen(FILE_NAME, "r");
    
//    FILE* fp = fopen(FILE_NAME, "a");
//    if(fp == NULL)
//    {
//        perror("fopen");// 打印系统错误信息
//        return 1;
//    }

    
//    char buffer[64];
//    while(fgets(buffer, sizeof(buffer) - 1, fp) != NULL)
//    {
//        // char * fgets ( char * str, int num, FILE * stream );
//        // 从stream从读取num个字符，将这些字符作为c-string存储到str中，fgers会默认为存储到str中的字符尾添加'\0'（因为是字符串），
//        // 而buffer大小是64，所以这个num最好是（buffer的大小减一）
//        // 返回值：若读取成功，返回读取到的字符串，否则，返回NULL
//        //
//        // int puts ( const char * str );
//        // 将str指向的c-string写入到标准输出流（stdout），并在结尾追加'\n'
//        
//        buffer[strlen(buffer) - 1] = '\0';// 取消puts的追加'\n'的作用
//        puts(buffer);
//    }

//    int cnt = 5;
//    while(cnt)
//    {
//        fprintf(fp, "%s:%d\n", "hello world", cnt--);
//    }
//
//    // 关闭文件fp
//    fclose(fp);

    return 0;
}
